package gr.upatras.uniexamtimetable;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Type;
import java.util.List;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

/**
 * A period of exams of variable length.
 * 
 * @author spirosag
 */
public class ExamPeriod {
	
	private String name;		//name of exams period
	private int numberOfDays;
	private int periodsPerDay;	//same number of exam periods per day
	private int startDate; 		//YYYYMMDD format
	private int endDate;		//YYYYMMDD format
	
	/**
	 * Constructs an object with the default values.
	 */
	ExamPeriod() {
		name = "sample period";
		numberOfDays = 0;
		periodsPerDay = 0;
		startDate = 00000000;
		endDate = 00000000;
	}

	/**
	 * Constructs an object with the given values
	 * 
	 * @param name the name of the period
	 * @param numberOfDays the length of the period in days
	 * @param periodsPerDay the number of exam periods per day
	 * @param startDate the starting date of the period
	 * @param endDate the ending time of the period
	 */
	public ExamPeriod(String name, int numberOfDays, int periodsPerDay,
			int startDate, int endDate) {
		this.name = name;
		this.numberOfDays = numberOfDays;
		this.periodsPerDay = periodsPerDay;
		this.startDate = startDate;
		this.endDate = endDate;
	}

		
	/**
	 * @return the name
	 */
	public String getName() {
		return name;
	}

	/**
	 * @param name the name to set
	 */
	public void setName(String name) {
		this.name = name;
	}

	/**
	 * @return the numberOfDays
	 */
	public int getNumberOfDays() {
		return numberOfDays;
	}

	/**
	 * @param numberOfDays the numberOfDays to set
	 */
	public void setNumberOfDays(int numberOfDays) {
		this.numberOfDays = numberOfDays;
	}

	/**
	 * @return the periodsPerDay
	 */
	public int getPeriodsPerDay() {
		return periodsPerDay;
	}

	/**
	 * @param periodsPerDay the periodsPerDay to set
	 */
	public void setPeriodsPerDay(int periodsPerDay) {
		this.periodsPerDay = periodsPerDay;
	}

	/**
	 * @return the startDate in YYYYMMDD format
	 */
	public int getStartDate() {
		return startDate;
	}

	/**
	 * @param startDate the startDate to set in YYYYMMDD format
	 */
	public void setStartDate(int startDate) {
		this.startDate = startDate;
	}

	/**
	 * @return the endDate in YYYYMMDD format
	 */
	public int getEndDate() {
		return endDate;
	}

	/**
	 * @param endDate the endDate to set in YYYYMMDD format
	 */
	public void setEndDate(int endDate) {
		this.endDate = endDate;
	}

	/**
	 * Prints all the characteristiscs of this object
	 */
	public void printStatus(){
		System.out.printf("Exam period name:" + name +
				" %nnumberOfDays:" + numberOfDays +
				" %nperiodsPerDay" + periodsPerDay +
				" %nstartDate:" + startDate +
				" %nendDate:" + endDate);
		System.out.printf("%n%n");		//+1 empty line
	}
	
	/**
	 * Returns the values of this object's variables in a single string 
	 * with explanatory labels.
	 * Overrides the <code>java.lang.Object.toString()</code>
	 * 
	 * @return a string with the values of this objects variables 
	 */
	public String toString() {
		StringBuilder stringBuilder = new StringBuilder();
		stringBuilder.append(String.format("Name: %s, ", name));
		stringBuilder.append(String.format("Num of days: %d, ", numberOfDays));
		stringBuilder.append(String.format("Start date: %d, ", startDate));
		stringBuilder.append(String.format("End date: %d, ", endDate));
		stringBuilder.append(String.format("Periods per day: %d, ", periodsPerDay));
		return stringBuilder.toString();
	}
	
	/**
	 * Exports a <code>List</code> of <code>ExamPeriod</code> objects to a json file.
	 * 
	 * @param examPeriods the {@code List<ExamPeriod>} to be exported 
	 * @param filename the name of file to export to
	 */
	public static void exportToJson(List<ExamPeriod> examPeriods, String filename) {
		
		BufferedWriter writer = null;
		Gson gson = new Gson();
		
		System.out.printf("Trying to export to %s ...%n", filename);
		try {
			writer = new BufferedWriter(new FileWriter(filename));
			
			/* ugly way to get the type of List<Room> */
			Type collectionType = new TypeToken<List<ExamPeriod>>(){}.getType();
			gson.toJson(examPeriods, collectionType, writer);
		} catch (IOException e) {
			System.err.printf("Sorry, couldn't export to %s.%n", filename);
			e.printStackTrace();
		} finally {
			try {
				writer.close();
			} catch (IOException e){
				System.err.println("Sorry, couldn't properly close the buffered writer");
				e.printStackTrace();
			}
		}
		
		System.out.printf("Success: %d obcjects were exported.%n", examPeriods.size());
	}	

	/* Imports a list of ExamPeriod objects from a json file */
	/**
	 * Imports a <code>List</code> of <code>ExamPeriod</code> 
	 * objects from a json file.
	 * 
	 * @param filename tha name of file to import from 
	 * @return a{@code List<ExamPeriod>}
	 */
	public static List<ExamPeriod> importFromJson(String filename) {
		
		BufferedReader reader = null;
		Gson gson = new Gson();
		List<ExamPeriod> examPeriods = null;
		
		System.out.printf("Trying to import from %s ...%n", filename);
		
		try {
			reader = new BufferedReader(new FileReader(filename));
			
			/* ugly way to get the type of List<Room> */
			Type collectionType = new TypeToken<List<ExamPeriod>>(){}.getType();
			examPeriods = gson.fromJson(reader, collectionType);
		} catch (IOException e) {
			System.out.printf("Sorry, couldn't import from %s.%n", filename);
			e.printStackTrace();
		} finally {
			try {
				reader.close();
			} catch (IOException e) {
				System.err.println("Sorry, couldn't close the buffered reader.");
				e.printStackTrace();
			}
		}

		System.out.printf("Success: %d obcjects were imported.%n", examPeriods.size());
		return examPeriods;
	}
}
